package com.hwtx.form.domain.listener;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hwtx.form.domain.def.FormConfigExt;
import com.hwtx.form.domain.def.meta.config.SelectComponentConfig;
import com.hwtx.form.domain.repo.FormConfigRepo;
import com.hwtx.form.domain.repo.FormRepo;
import com.hwtx.form.persistence.entity.FormConfigQuery;
import com.hwtx.form.util.FormUtil;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;

import static com.hwtx.form.domain.FormConstants.*;

@Component
public class DictFormDataChangeInterceptor extends AbstractFormDataChangeInterceptor {
    @Resource
    private FormConfigRepo formConfigRepo;
    @Resource
    private FormRepo formRepo;

    @Override
    public Object after(FormDataChangeEvent event) {
        if (!Objects.equals("sys_dict", event.getDataModel().getMaster())) {
            return null;
        }
        List<FormConfigQuery> formConfigs = formConfigRepo.listFormConfigQueryWithExt();
        if (CollectionUtils.isEmpty(formConfigs)) {
            return null;
        }
        Map<Long, List<FormConfigExt>> formConfigExtMap = new HashMap<>();
        formConfigs.forEach(config -> {
            FormConfigExt formConfigExt = FormUtil.getFormConfigExt(config.getExt());
            if (formConfigExt == null) {
                return;
            }
            if ((formConfigExt.getQuery() != null && formConfigExt.getQuery().getConfigCtr() != null &&
                    SelectComponentConfig.getDict(formConfigExt.getQuery().getConfigCtr().getComExt()) != null) ||
                    (formConfigExt.getForm() != null && formConfigExt.getForm().getConfigCtr() != null &&
                            SelectComponentConfig.getDict(formConfigExt.getForm().getConfigCtr().getComExt()) != null)) {
                formConfigExtMap.compute(config.getFormId(), (k, v) -> {
                    if (v == null) {
                        v = Lists.newArrayList();
                    }
                    v.add(formConfigExt);
                    return v;
                });
            }
        });
        Set<Object> pids = Sets.newHashSet();
        if (Objects.equals(OPERATION_EDIT, event.getType()) || Objects.equals(OPERATION_ADD, event.getType())) {
            for (int i = 0; i < event.getHandleItems().size(); i++) {
                if (Objects.equals(event.getHandleItems().get(i), "pid")) {
                    Long pid = Long.valueOf(event.getData().get(i).toString());
                    if (!Objects.equals(0L, pid)) {
                        pids.add(pid);
                    }
                }
            }
        } else if (Objects.equals(OPERATION_DELETE, event.getType())) {
            if (CollectionUtils.isNotEmpty(event.getRemoveItems())) {
                for (Map<String, Object> removeItem : event.getRemoveItems()) {
                    if (removeItem.containsKey("pid") && !Objects.equals(0L, removeItem.get("pid"))) {
                        pids.add(removeItem.get("pid"));
                    }
                }
            }
        }
        Set<Long> ret = new HashSet<>();

        if (CollectionUtils.isNotEmpty(pids)) {
            formConfigExtMap.forEach((formId, formConfigExts) -> formConfigExts.forEach(formConfigExt -> {
                String dict;
                if (formConfigExt.getForm() != null && formConfigExt.getForm().getConfigCtr() != null) {
                    dict = SelectComponentConfig.getDict(formConfigExt.getForm().getConfigCtr().getComExt());
                    if (StringUtils.isNotEmpty(dict) && pids.contains(Long.parseLong(dict))) {
                        ret.add(formId);
                    }
                }
                if (formConfigExt.getQuery() != null && formConfigExt.getQuery().getConfigCtr() != null) {
                    dict = SelectComponentConfig.getDict(formConfigExt.getQuery().getConfigCtr().getComExt());
                    if (StringUtils.isNotEmpty(dict) && pids.contains(Long.parseLong(dict))) {
                        ret.add(formId);
                    }
                }
            }));
        }
        List<String> formNames = ret.stream().map(formId -> formRepo.getFormNameById(formId)).toList();
        if (CollectionUtils.isNotEmpty(formNames)) {
            return "字典数据变更，请刷新表单：" + String.join(",", formNames);
        }
        return null;
    }
}
